﻿Imports Microsoft.Win32
Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Runtime.InteropServices
Imports Kofax.ACWFLib
Imports AllStateWFA.clsExportData
Imports AllStateWFA.KofaxXmlSchema

Namespace WFAGetFieldInfo
    <Guid("ED1B171D-C72B-4152-972C-2B1F3C4E7F49"), _
    ClassInterface(ClassInterfaceType.None), _
    ProgId("AllStateWFA.clsAllstateWFAgent"), CLSCompliant(False)> _
    Public Class clsAllstateWFAgent
        Implements IACWorkflowAgent
        Implements IDisposable

#Region "Common Objects"
        'Process definition constants
        Private oProcID As String = System.Diagnostics.Process.GetCurrentProcess.Id.ToString
        Private VersionInfo As Version = System.Reflection.Assembly.GetExecutingAssembly.GetName.Version
        Private sVersion As String = VersionInfo.Major & "." & VersionInfo.Minor & "." & VersionInfo.Build & "." & VersionInfo.Revision
        Private StartTime As Date = Now

        'Log\Config file
        Const LOGFILENAME As String = "AllstateGenericXMLWFA.Log"
        Const ERRORFILENAME As String = "AllstateGenericXMLWFA.Err"
        Private SqlConnectionString As String
        Private GenericFilePrefix As String = DatePart(DateInterval.Year, Now) & "." & DatePart(DateInterval.DayOfYear, Now) & "." & System.Environment.MachineName & "."
        Private LogStream As FileStream
        Private sIniPath As String

        'Kofax Root objects.
        Private XMLOutputPath As String
        Private BatchClassName As String

        'Private oRootSetupElement As ACDataElement = Nothing
        Private oWFData As Kofax.ACWFLib.ACWorkflowData
        Private oRuntimeRootElement As ACDataElement = Nothing

        'Kofax Batch objects.
        'Private oRootSetupElement As ACDataElement = Nothing
        Private oBatchElement As ACDataElement = Nothing
        Private oBatchFieldsElement As ACDataElement = Nothing
        Private oBatchFieldsColletion As ACDataElementCollection = Nothing
        Private oBatchFieldElement As ACDataElement = Nothing
        Private oBatchHistorysElement As ACDataElement = Nothing
        Private oBatchHistorysCollection As ACDataElementCollection = Nothing
        Private oBatchHistoryElement As ACDataElement = Nothing
        Private oBatchCustomPropertiesElement As ACDataElement = Nothing
        Private oBatchCustomPropertiesCollection As ACDataElementCollection = Nothing

        'Kofax Folder objects.
        Private oFoldersRootElement As ACDataElement = Nothing
        Private oFoldersChildElement As ACDataElementCollection = Nothing

        'Kofax Document objects.
        Private oDocumentsElement As ACDataElement = Nothing
        Private oDocumentsCollection As ACDataElementCollection = Nothing
        Private oDocumentElement As ACDataElement = Nothing

        'Kofax Field objects.
        Private oIndexFieldsElement As ACDataElement = Nothing
        Private oIndexFieldsCollection As ACDataElementCollection = Nothing

        'Other Kofax Objects
        Dim oPossibleModules As ACWorkflowModules = Nothing
        Dim sEarlyReleaseQueue As String
        Dim sEarlyReleasePath As String

        'Reporting Objects
        Dim BatchFields(-1) As String
        Dim FolderFields(-1) As String
        Dim DocumentFields(-1) As String

        Private disposedValue As Boolean = False
#End Region

#Region "New"
        'Entry point for code.
        Public Sub New()
            'Initialize all needed object.
            MyBase.New()

            'Setup the logging for the assembly.
            CreateLoggingObjects()
        End Sub

#End Region

#Region "Entry Point Functions"

        Public Sub ProcessWorkflow(ByRef oWorkflowData As Kofax.ACWFLib.ACWorkflowData) Implements Kofax.ACWFLib.IACWorkflowAgent.ProcessWorkflow
            oWFData = oWorkflowData
            LogResults("ProcessWorkflow", "Log opened.", LogType.Info, LogSettings.Local)

            'Get all needed Kofax objects.
            GetKofaxBatchObjects(oWorkflowData)

            Try

                'Set the application defaults.
                If SetDefaults() = False Then
                    LogResults("ProcessWorkflow", "Default settings error.", LogType.Error, LogSettings.Local)
                    Exit Try
                Else
                    LogResults("ProcessWorkflow", "Default settings complete.", LogType.Info, LogSettings.Local)
                End If

                'If settings are incorrect then exit.
                If CheckSettings() = False Then
                    LogResults("ProcessWorkflow", "Settings error.", LogType.Error, LogSettings.Local)
                    Exit Try
                Else
                    LogResults("ProcessWorkflow", "Settings Complete", LogType.Info, LogSettings.Local)
                End If

                'Do not procede with any changes to the batch if it is in error.
                If (oWorkflowData.NextState.Name = "Error") Then
                    LogResults("ProcessWorkflow", "Batch not in Ready status.", LogType.Error, LogSettings.Local)
                    Throw New Exception("Batch in error state.")
                End If

                'Check to see if the batch needs and early release of data.
                Select Case oWorkflowData.CurrentModule.Name.ToString
                    Case Is = Me.sEarlyReleaseQueue
                        'Export the kofax xml data to the LZ.
                        ExportBatchData(Me.sEarlyReleasePath)
                End Select

                'Release the data when it is completed.
                Select Case oWorkflowData.NextModule.Name.ToString
                    Case "Export"
                        'Export the kofax xml data to the LZ.
                        ExportBatchData(XMLOutputPath)
                    Case Else
                        'Check Priority for custom property.
                        ChangeBatchPriority()
                End Select

            Catch ex As Exception
                oWorkflowData.NextState = oWorkflowData.PossibleStates("Error")
                oWorkflowData.ErrorText = "Error exporting batch, check log file."
                LogResults("ProcessWorkflow", "ProcessWorkflow error, sending batch to QC.", LogType.Error, LogSettings.Local)
                LogResults("ProcessWorkflow", "ProcessWorkflow error." & "~" & ex.StackTrace & vbCrLf & "~" & ex.Message, LogType.Error, LogSettings.Local)
            End Try

            'Try to clean up the com objects
            BatchReport(oWorkflowData)

            'Update Batch level reporting.
            Dispose(True)

            'Close the logfile.
            If Not LogStream Is Nothing Then
                LogResults("ProcessWorkflow", "Log closed.", LogType.Info, LogSettings.Local)
                Trace.Listeners.Clear()
                Trace.Close()
                LogStream.Close()
                LogStream.Dispose()
            End If

        End Sub

        Private Sub GetKofaxBatchObjects(ByVal oWorkflowData As Kofax.ACWFLib.ACWorkflowData)
            'Root Elements
            'oRootSetupElement = oWorkflowData.ExtractSetupACDataElement(lNO_HINTS)
            oRuntimeRootElement = oWorkflowData.ExtractRuntimeACDataElement(lNO_HINTS)
            oPossibleModules = oWorkflowData.PossibleModules

            'Batch Elements
            oBatchElement = oRuntimeRootElement.FindChildElementByName("Batch")
            oBatchFieldsElement = oBatchElement.FindChildElementByName("BatchFields")
            oBatchFieldsColletion = oBatchFieldsElement.FindChildElementsByName("BatchField")
            oBatchHistorysElement = oBatchElement.FindChildElementByName("BatchHistoryEntries")
            oBatchHistorysCollection = oBatchHistorysElement.FindChildElementsByName("BatchHistoryEntry")
            oBatchCustomPropertiesElement = oBatchElement.FindChildElementByName("BatchCustomProperties")
            oBatchCustomPropertiesCollection = oBatchCustomPropertiesElement.FindChildElementsByName("BatchCustomProperty")

            'Folder Elements
            oFoldersRootElement = oBatchElement.FindChildElementByName("Folders")
            oFoldersChildElement = oFoldersRootElement.FindChildElementsByName("Folder")
  
            'Document Elements
            oDocumentsElement = oBatchElement.FindChildElementByName("Documents")
            oDocumentsCollection = oDocumentsElement.FindChildElementsByName("Document")

            LogResults("GetKofaxBatchObjects", "Kofax Objects collection complete.", LogType.Info, LogSettings.Local)

        End Sub

#End Region

#Region "Export Code"

        Private Sub ExportBatchData(ByVal ExportPath As String)
            Dim clsExportData As New clsExportData(oBatchData:=oBatchElement)
            Dim xImportSession As New KofaxXmlSchema.ImportSession
            Dim xBatch As New ImportSession.Batch

            LogResults("ExportBatchData", "XML object creation start.", LogType.Info, LogSettings.Local)
            With xBatch
                .BatchClassName = oBatchElement.AttributeValue("BatchClassName")
                .Name = Replace(oBatchElement.AttributeValue("Name"), "/", "-")
                .ExternalBatchID = oBatchElement.AttributeValue("ExternalBatchID")
                .CreationDateTime = oBatchElement.AttributeValue("CreationDateTime")
                '.Priority = oBatchElement.AttributeValue("Priority")

                .BatchFields = clsExportData.GetBatchFields(oBatchFieldsColletion)
                .Folders = clsExportData.GetFolders(oFoldersChildElement)
                .Documents = clsExportData.GetDocuments(oDocumentsCollection)
                .BatchHistoryEntries = clsExportData.GetBatchHistory(oBatchHistorysCollection)
            End With

            ReDim Preserve xImportSession.Batches(0)
            xImportSession.Batches(0) = xBatch

            LogResults("ExportBatchData", "XML object creation end.", LogType.Info, LogSettings.Local)

            Dim sBatchOutputname As String = xBatch.BatchClassName & "_" & xBatch.ExternalBatchID & "_" & GetDateFormat(xBatch.CreationDateTime)

            If File.Exists(XMLOutputPath & sBatchOutputname & ".XML") = True Then
                LogResults("ExportBatchData", "Duplicate XML found outputing unique duplicate file.", LogType.Info, LogSettings.Local)
                Serializebatch(xImportSession, ExportPath & sBatchOutputname & "_" & System.Guid.NewGuid.ToString & ".DUP")
            Else
                LogResults("ExportBatchData", "Duplicate XML not found outputing normal xml.", LogType.Info, LogSettings.Local)
                Serializebatch(xImportSession, ExportPath & sBatchOutputname & ".XML")
            End If

        End Sub

        Private Sub ExportBatchTrackingData(ByVal CopyImages As Boolean)
            Dim clsExportData As New clsExportData(oBatchData:=oBatchElement)
            Dim xImportSession As New KofaxXmlSchema.ImportSession
            Dim xBatch As New ImportSession.Batch

            LogResults("ExportBatchTrackingData", "XML object creation start.", LogType.Info, LogSettings.Local)
            With xBatch
                .BatchClassName = oBatchElement.AttributeValue("BatchClassName")
                .Name = Replace(oBatchElement.AttributeValue("Name"), "/", "-")
                .ExternalBatchID = oBatchElement.AttributeValue("ExternalBatchID")
                .CreationDateTime = oBatchElement.AttributeValue("CreationDateTime")
                .Priority = oBatchElement.AttributeValue("Priority")

                .BatchFields = clsExportData.GetBatchFields(oBatchFieldsColletion)
                .Folders = clsExportData.GetFolders(oFoldersChildElement)
                .Documents = clsExportData.GetDocuments(oDocumentsCollection)
                .BatchHistoryEntries = clsExportData.GetBatchHistory(oBatchHistorysCollection)
            End With

            ReDim Preserve xImportSession.Batches(0)
            xImportSession.Batches(0) = xBatch

            LogResults("ExportBatchTrackingData", "XML object creation end.", LogType.Info, LogSettings.Local)

            Dim sBatchOutputname As String = xBatch.BatchClassName & "_" & xBatch.ExternalBatchID & "_" & GetDateFormat(xBatch.CreationDateTime)

            If File.Exists(XMLOutputPath & sBatchOutputname & ".XML") = True Then
                LogResults("ExportBatchTrackingData", "Duplicate XML found outputing unique duplicate file.", LogType.Info, LogSettings.Local)
                Serializebatch(xImportSession, XMLOutputPath & sBatchOutputname & "_" & System.Guid.NewGuid.ToString & ".DUP")
            Else
                LogResults("ExportBatchTrackingData", "Duplicate XML not found outputing normal xml.", LogType.Info, LogSettings.Local)
                Serializebatch(xImportSession, XMLOutputPath & sBatchOutputname & ".XML")
            End If


        End Sub

        Private Function GetXMLSchemaData() As KofaxXmlSchema.ImportSession
            Dim clsExportData As New clsExportData(oBatchData:=oBatchElement)
            Dim xImportSession As New KofaxXmlSchema.ImportSession
            Dim xBatch As New ImportSession.Batch

            LogResults("ExportBatchData", "XML object creation start.", LogType.Info, LogSettings.Local)
            With xBatch
                .BatchClassName = oBatchElement.AttributeValue("BatchClassName")
                .Name = Replace(oBatchElement.AttributeValue("Name"), "/", "-")
                .ExternalBatchID = oBatchElement.AttributeValue("ExternalBatchID")
                .CreationDateTime = oBatchElement.AttributeValue("CreationDateTime")
                '.Priority = oBatchElement.AttributeValue("Priority")

                .BatchFields = clsExportData.GetBatchFields(oBatchFieldsColletion)
                .Folders = clsExportData.GetFolders(oFoldersChildElement)
                .Documents = clsExportData.GetDocuments(oDocumentsCollection)
                .BatchHistoryEntries = clsExportData.GetBatchHistory(oBatchHistorysCollection)
            End With

            ReDim Preserve xImportSession.Batches(0)
            xImportSession.Batches(0) = xBatch

            Return xImportSession
        End Function

#End Region

#Region "User\System Reporting"

        Private Sub BatchReport(ByVal oWorkflowData As Kofax.ACWFLib.ACWorkflowData)
            Try
                Dim xImportSession As KofaxXmlSchema.ImportSession = GetXMLSchemaData()
                modQueueReporting.UpdateBatchEvents(oWorkflowData, oBatchElement, xImportSession.Batches(0), Me.SqlConnectionString, Me.BatchFields, Me.FolderFields, Me.DocumentFields)

                LogResults("BatchReport", "Reporting complete.", LogType.Info, LogSettings.Local)

            Catch ex As Exception
                LogResults("BatchReport", ex.Message, LogType.Error, LogSettings.Local)
            End Try

        End Sub

        Private Sub ChangeBatchPriority()
            Dim sBatchSectionName As String = BatchClassName & ".BatchSettings"
            Dim sBatchPriorityProperty As String = INIRead(sIniPath, sBatchSectionName, "BatchPriority", "")
            Dim sPreBatchPriorityChange As String = oBatchElement.AttributeValue("Priority")
            Dim sPostBatchPriorityChange As String = ""

            'Get the batch priority setting and set a blank value if not found.
            Select Case sBatchPriorityProperty
                Case ""
                    INIWrite(sIniPath, sBatchSectionName, "BatchPriority", "N\A")
                    Exit Sub
                Case "N\A"
                    'Do Nothing
                    Exit Sub
                Case Else
                    LogResults("ChangeBatchPriority", "Matched a batch for priority to change.", LogType.Info, LogSettings.Local)
                    Dim xImportSession As KofaxXmlSchema.ImportSession = GetXMLSchemaData()

                    'Loop through folders if the exist.
                    If xImportSession.Batches(0).Folders.Length > 0 Then
                        For Each oFolder As KofaxXmlSchema.Folder In xImportSession.Batches(0).Folders
                            For Each oDoc As KofaxXmlSchema.Document In oFolder.Documents
                                For Each oProp As KofaxXmlSchema.Document.DocumentCustomStorageString In oDoc.DocumentCustomStorageStrings
                                    If oProp.Name = sBatchPriorityProperty Then
                                        If (IsNumeric(oProp.Value)) = True And (IsNumeric(oProp.Value) <= 10) Then
                                            oBatchElement.AttributeValue("Priority") = oProp.Value
                                            sPostBatchPriorityChange = oBatchElement.AttributeValue("Priority")
                                            LogResults("ChangeBatchPriority", "Batch priority changed from " & sPreBatchPriorityChange & " To " & sPostBatchPriorityChange, LogType.Info, LogSettings.Local)
                                            Exit Sub
                                        End If
                                    End If
                                Next
                            Next
                        Next
                    Else
                        'Loop through documents if folders do not exist.
                        For Each oDoc As KofaxXmlSchema.Document In xImportSession.Batches(0).Documents
                            For Each oProp As KofaxXmlSchema.Document.DocumentCustomStorageString In oDoc.DocumentCustomStorageStrings
                                If oProp.Name = sBatchPriorityProperty Then
                                    If (IsNumeric(oProp.Value)) = True And (IsNumeric(oProp.Value) <= 10) Then
                                        oBatchElement.AttributeValue("Priority") = oProp.Value
                                        sPostBatchPriorityChange = oBatchElement.AttributeValue("Priority")
                                        LogResults("ChangeBatchPriority", "Batch priority changed from " & sPreBatchPriorityChange & " To " & sPostBatchPriorityChange, LogType.Info, LogSettings.Local)
                                        Exit Sub
                                    End If
                                End If
                            Next
                        Next
                    End If
            End Select
        End Sub

#End Region

#Region "Common Functions"

        Private Function Serializebatch(ByVal ImportSession As KofaxXmlSchema.ImportSession, ByVal Outputpath As String) As Boolean
            Try
                LogResults("Serializebatch", "Beginning serialization.", LogType.Info, LogSettings.Local)
                Dim oSer As New Xml.Serialization.XmlSerializer(ImportSession.GetType)
                Dim oWriter As New XmlTextWriter(Outputpath, New System.Text.ASCIIEncoding)
                oWriter.Formatting = Formatting.Indented
                oSer.Serialize(oWriter, ImportSession)
                oWriter.Flush()
                oWriter.Close()
                LogResults("Serializebatch", "Serialization Completed.", LogType.Info, LogSettings.Local)
            Catch ex As Exception
                LogResults("Serializebatch", "Serialization Failed." & "~" & ex.StackTrace & "~" & ex.Message, LogType.Error, LogSettings.Local)
                Throw New Exception(ex.Message, ex.InnerException)
            End Try

        End Function

        'Dateformat YYYYDDDHHMMSSfff 2010365125959999 
        Private Function GetDateFormat(ByVal sDate As String) As String
            Return CDate(sDate).DayOfYear.ToString.PadLeft(3, "0") & Format(CDate(sDate).TimeOfDay.TotalSeconds, "000000")
        End Function

#End Region

#Region "Settings code."

        Private Sub CreateLoggingObjects()
            Dim sRootServerLogPath As String = ""
            Dim sFullLogPath As String = ""
            Dim sLogFolderName As String = "AllstateGenericXMLWFA"
            Dim sINIFileName As String = "AllstateGenericXMLWFA.INI"
            Dim sLogFileName As String = GenericFilePrefix & LOGFILENAME

            'Set up the logging path.
            If Not (My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Kofax Image Products\Ascent Capture\3.0", "ServerPath", Nothing)) Is Nothing Then
                'Look for the 64bit path.
                sRootServerLogPath = My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Kofax Image Products\Ascent Capture\3.0", "ServerPath", Nothing)
                sFullLogPath = Path.Combine(sRootServerLogPath & "\Logs\" & sLogFolderName, sLogFileName)
            ElseIf Not (My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Kofax Image Products\Ascent Capture\3.0", "ServerPath", Nothing)) Is Nothing Then
                'Look for the 32bit path.
                sRootServerLogPath = My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Kofax Image Products\Ascent Capture\3.0", "ServerPath", Nothing)
                sFullLogPath = Path.Combine(sRootServerLogPath & "\Logs\" & sLogFolderName, sLogFileName)
            Else
                'Use default directory.
                sFullLogPath = Path.Combine(System.Environment.CurrentDirectory, sLogFileName)
            End If

            'Set the INI settings path on startup.
            sIniPath = Path.Combine(sRootServerLogPath & "\Config\", sINIFileName)
            CreateDefaultINI(sIniPath)

            If Directory.Exists(Path.GetDirectoryName(sFullLogPath)) = False Then
                Directory.CreateDirectory(Path.GetDirectoryName(sFullLogPath))
            End If

            If LogStream Is Nothing Then
                Try
                    LogStream = New FileStream(sFullLogPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)
                    Dim objTraceListener As TextWriterTraceListener = New TextWriterTraceListener(LogStream)

                    Trace.Listeners.Add(objTraceListener)
                    Trace.AutoFlush = True
                Catch ex As Exception
                End Try
            End If

        End Sub

        Private Sub CreateDefaultINI(ByVal IniPath As String)
            If File.Exists(IniPath) = False Then
                Dim oStreamWriter As New StreamWriter(IniPath)
                oStreamWriter.Flush()
                oStreamWriter.Close()
                INIWrite(IniPath, "DefaultSettings", "XMLOutputPath", "C:\temp\")
                INIWrite(IniPath, "DefaultSettings", "ImageOutput", "False")
                INIWrite(IniPath, "DefaultSettings", "ReportingDBSettings", "server=;UID=;pwd=;database=")
            End If
        End Sub

        Private Function SetDefaults() As Boolean
            'Make sure to log as much as possible.
            LogResults("SetDefaults", "Kofax Batchid : " & oBatchElement.AttributeValue("ExternalBatchID").ToString.ToUpper.PadLeft(8, "0"), LogType.Info, LogSettings.Local)
            LogResults("SetDefaults", "Batchclass Name : " & oBatchElement.AttributeValue("BatchClassName").ToString.ToUpper, LogType.Info, LogSettings.Local)
            LogResults("SetDefaults", "BatchName : " & oBatchElement.AttributeValue("Name").ToString.ToUpper, LogType.Info, LogSettings.Local)

            BatchClassName = oBatchElement.AttributeValue("BatchClassName").ToString

            'Get the xml output path from the Section for the batchclass.
            'Create an entry if needed and set the default location for the data.
            Dim sBatchSectionName As String = BatchClassName & ".BatchSettings"
            If INIRead(sIniPath, sBatchSectionName, "XmlOutput", "") = "" Then
                INIWrite(sIniPath, sBatchSectionName, "XmlOutput", oBatchElement.AttributeValue("ImageDirectory") & "\")
            End If

            'Read the database connection settings from the ini file.
            Me.SqlConnectionString = INIRead(sIniPath, "DefaultSettings", "ReportingDBSettings")
            LogResults("SetDefaults", "SQL Settings captured." & XMLOutputPath, LogType.Info, LogSettings.Server)

            'Get the reporting fields by object level.
            LogResults("SetDefaults", "Tracking fields settings captured." & XMLOutputPath, LogType.Info, LogSettings.Server)

            'Batch level fields.
            Dim sBatchFields As String = INIRead(sIniPath, sBatchSectionName, "BatchFields")
            If sBatchFields.Length = 0 Then
                INIWrite(sIniPath, sBatchSectionName, "BatchFields", "N\A")
            ElseIf sBatchFields = "N\A" Then
            Else
                Me.BatchFields = Split(sBatchFields, ",")
            End If

            'Folder level fields.
            Dim sFolderFields As String = INIRead(sIniPath, sBatchSectionName, "FolderFields")
            If sFolderFields.Length = 0 Then
                INIWrite(sIniPath, sBatchSectionName, "FolderFields", "N\A")
            ElseIf sFolderFields = "N\A" Then
            Else
                Me.FolderFields = Split(sFolderFields, ",")
            End If

            'Document level fields.
            Dim sDocumentFields As String = INIRead(sIniPath, sBatchSectionName, "DocumentFields")
            If sDocumentFields.Length = 0 Then
                INIWrite(sIniPath, sBatchSectionName, "DocumentFields", "N\A")
            ElseIf sDocumentFields = "N\A" Then
            Else
                Me.DocumentFields = Split(sDocumentFields, ",")
            End If

            'Early release queue name.
            Me.sEarlyReleaseQueue = INIRead(sIniPath, sBatchSectionName, "EarlyReleaseQueue")
            If Me.sEarlyReleaseQueue.Length = 0 Then
                INIWrite(sIniPath, sBatchSectionName, "EarlyReleaseQueue", "N\A")
            ElseIf Me.sEarlyReleaseQueue = "N\A" Then
            End If

            'Early release path.
            Me.sEarlyReleasePath = INIRead(sIniPath, sBatchSectionName, "EarlyReleasePath")
            If Me.sEarlyReleasePath.Length = 0 Then
                INIWrite(sIniPath, sBatchSectionName, "EarlyReleasePath", "N\A")
            ElseIf Me.sEarlyReleasePath = "N\A" Then
            Else
                If Right(sEarlyReleasePath, 1) <> "\" Then sEarlyReleasePath &= "\"
            End If

            'Read the batch settings from the ini file.
            XMLOutputPath = INIRead(sIniPath, sBatchSectionName, "XmlOutput")
            If Right(XMLOutputPath, 1) <> "\" Then XMLOutputPath &= "\"
            LogResults("SetDefaults", "OutputPath set as : " & XMLOutputPath, LogType.Info, LogSettings.Server)
            Return True

            'As a last resort output the xml to the image directory of the batch class.
            XMLOutputPath = oBatchElement.AttributeValue("ImageDirectory")
            If Right(XMLOutputPath, 1) <> "\" Then XMLOutputPath &= "\"
            XMLOutputPath &= "XMLOUTPUT\"
            LogResults("SetDefaults", "OutputPath set as : " & XMLOutputPath, LogType.Info, LogSettings.Server)
            Return True

        End Function

        Private Function CheckSettings() As Boolean

            'Check output path.
            If Directory.Exists(XMLOutputPath) = False Then
                Try
                    Directory.CreateDirectory(XMLOutputPath)
                    LogResults("CheckSettings", "Directory created :" & XMLOutputPath, LogType.Info, LogSettings.Local)
                Catch ex As Exception
                    LogResults("CheckSettings", "CheckSettings error ~" & ex.StackTrace & " ~ " & ex.Message, LogType.Error, LogSettings.Local)
                    Return False
                End Try
            End If

            'Check early release path.
            If Directory.Exists(Me.sEarlyReleasePath) = False Then
                Try
                    Directory.CreateDirectory(Me.sEarlyReleasePath)
                    LogResults("CheckSettings", "Directory created :" & Me.sEarlyReleasePath, LogType.Info, LogSettings.Local)
                Catch ex As Exception
                    LogResults("CheckSettings", "CheckSettings error ~" & ex.StackTrace & " ~ " & ex.Message, LogType.Error, LogSettings.Local)
                    Return False
                End Try
            End If

            Return True
        End Function

#End Region

#Region "Logging"

        Private Sub LogResults(ByVal FunctionName As String, ByVal Message As String, ByVal MessageType As LogType, ByVal LogLocation As LogSettings)
            Try
                Trace.WriteLine(GetLogMessageData() & FunctionName & "|" & MessageType.ToString & "|" & Message)

                If MessageType = LogType.Error Then
                    File.AppendAllText(Path.GetDirectoryName(LogStream.Name) & "\" & GenericFilePrefix & ERRORFILENAME, vbCrLf & GetLogMessageData() & FunctionName & "|" & MessageType.ToString & "|" & Message)
                End If

            Catch ex As Exception
                Throw ex
            End Try

        End Sub

        Private Function GetLogMessageData() As String
            Dim EndTime As Date = Now
            Dim RunLength As Global.System.TimeSpan = EndTime.Subtract(StartTime)

            Dim sLogPrefixData As String = _
            "Version:" & sVersion & "-" & AssemblyBuildDate.ToString & "|" & _
            oProcID.ToString.PadLeft(8, "0") & "|" & _
            EndTime.ToString & "|" & _
            New TimeSpan(RunLength.Ticks).ToString & "|" & _
            oWFData.CurrentModule.Name.ToString & "|" & _
            System.Environment.MachineName & "|" & _
            System.Environment.UserDomainName & "\" & System.Environment.UserName & "|"

            Return sLogPrefixData
        End Function

        Private Enum LogSettings
            [Local]
            [Server]
            [LocalAndServer]
        End Enum

        Private Enum LogType
            [Error]
            [Info]
        End Enum

        Private Function AssemblyBuildDate() As DateTime
            Dim oVersion As System.Version = System.Reflection.Assembly.GetExecutingAssembly.GetName.Version
            Dim oBuildDate As DateTime

            oBuildDate = New DateTime(2000, 1, 1, 0, 0, 0).AddDays(oVersion.Build).AddSeconds(oVersion.Revision * 2)
            If TimeZone.IsDaylightSavingTime(oBuildDate, TimeZone.CurrentTimeZone.GetDaylightChanges(oBuildDate.Year)) Then
                oBuildDate = oBuildDate.AddHours(1)
            End If

            Return oBuildDate
        End Function

#End Region

#Region "Disposal Code."

        'IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            'Clean up the unused com objects.
            Try
                LogResults("Dispose", "Releasing com objects start.", LogType.Info, LogSettings.Local)

                If Not (oBatchElement Is Nothing) Then Marshal.FinalReleaseComObject(oBatchElement)
                If Not (oBatchFieldsElement Is Nothing) Then Marshal.FinalReleaseComObject(oBatchFieldsElement)
                If Not (oBatchFieldsColletion Is Nothing) Then Marshal.FinalReleaseComObject(oBatchFieldsColletion)
                If Not (oBatchFieldElement Is Nothing) Then Marshal.FinalReleaseComObject(oBatchFieldElement)
                If Not (oBatchHistorysElement Is Nothing) Then Marshal.FinalReleaseComObject(oBatchHistorysElement)
                If Not (oBatchHistorysCollection Is Nothing) Then Marshal.FinalReleaseComObject(oBatchHistorysCollection)
                If Not (oBatchHistoryElement Is Nothing) Then Marshal.FinalReleaseComObject(oBatchHistoryElement)
                If Not (oFoldersRootElement Is Nothing) Then Marshal.FinalReleaseComObject(oFoldersRootElement)
                If Not (oFoldersChildElement Is Nothing) Then Marshal.FinalReleaseComObject(oFoldersChildElement)
                If Not (oDocumentsElement Is Nothing) Then Marshal.FinalReleaseComObject(oDocumentsElement)
                If Not (oDocumentsCollection Is Nothing) Then Marshal.FinalReleaseComObject(oDocumentsCollection)
                If Not (oDocumentElement Is Nothing) Then Marshal.FinalReleaseComObject(oDocumentElement)
                If Not (oIndexFieldsElement Is Nothing) Then Marshal.FinalReleaseComObject(oIndexFieldsElement)
                If Not (oIndexFieldsCollection Is Nothing) Then Marshal.FinalReleaseComObject(oIndexFieldsCollection)

                LogResults("Dispose", "Releasing com objects end.", LogType.Info, LogSettings.Local)
            Catch ex As Exception
                oWFData.NextState = oWFData.PossibleStates("Error")
                LogResults("Dispose", "Releasing com objects failed." & "~" & ex.StackTrace & "~" & ex.Message, LogType.Error, LogSettings.Local)
            End Try
        End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub

#End Region

    End Class
End Namespace
